package org.snia.server.dispatcher;

import java.util.Map;
import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.snia.cdmi.ErrorCodes;
import org.snia.cdmi.auth.Principal;
import org.snia.cdmi.exception.InternalException;
import org.snia.cdmi.model.AccessControlList;
import org.snia.cdmi.model.Container;
import org.snia.cdmi.model.ContainerProperties;
import org.snia.cdmi.model.DataObject;
import org.snia.cdmi.model.DataObjectProperties;
import org.snia.cdmi.model.InputDataObject;
import org.snia.cdmi.model.MetaDataObject;
import org.snia.server.ejb.container.LocalContainerOperation;
import org.snia.server.ejb.dataobject.LocalDataObjectOperation;

/**
 * 单机版本，用于测试
 * 
 * @author Administrator
 * 
 */
public class SingleDispatcher implements Dispatcher {
	private static Log log = LogFactory.getLog(SingleDispatcher.class);

	private Principal principal;

	private InitialContext ctx = null;
	private LocalContainerOperation local = null;
	private LocalDataObjectOperation obj_local = null;

	@Override
	public void createContainer(Container container) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			local = (LocalContainerOperation) ctx.lookup("ContainerBean/local");
			// local = new ContainerBean();
			local.createContainer(container, principal);
		} catch (NamingException e1) {
			log.error(e1.getMessage());
			throw new InternalException(ErrorCodes.InternalError);
		}

	}

	@Override
	public void deleteContainer(String name) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			local = (LocalContainerOperation) ctx.lookup("ContainerBean/local");
			// local = new ContainerBean();
			// 校验ACL是否有删除权限
			local.deleteContainer(name, principal);
		} catch (NamingException e1) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public void setAccessControlPolicy(String name, AccessControlList acl) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			local = (LocalContainerOperation) ctx.lookup("ContainerBean/local");
			// local = new ContainerBean();
			local.setAccessControlPolicy(name, acl, this.principal);
		} catch (NamingException e1) {
			throw new InternalException(ErrorCodes.InternalError);
		}

	}

	@Override
	public Map<String, String> getAccessControlList(String name) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			local = (LocalContainerOperation) ctx.lookup("ContainerBean/local");
			// local = new ContainerBean();
			return local.getAccessControlList(name, this.principal);
		} catch (NamingException e1) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public ContainerProperties getProperties(String name, boolean withMetadata) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			local = (LocalContainerOperation) ctx.lookup("ContainerBean/local");
			// local = new ContainerBean();
			return local.getProperties(name, withMetadata, this.principal);
		} catch (NamingException e) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public void setUserMetadata(String name, Map<String, String> meta) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			local = (LocalContainerOperation) ctx.lookup("ContainerBean/local");
			// local = new ContainerBean();
			local.setUserMetadata(name, meta, this.principal);
		} catch (NamingException e) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public Map<String, String> getUserMetadata(String name) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			local = (LocalContainerOperation) ctx.lookup("ContainerBean/local");
			// local = new ContainerBean();
			return local.getUserMetadata(name, this.principal);
		} catch (NamingException e) {
			throw new InternalException(ErrorCodes.InternalError);
		}

	}

	// @Override
	// public MetaContainer getMetaContainer(String name) {
	// // 检查参数
	// if (name == null || name.trim().length() < 1) {
	// throw new InternalException(ErrorCodes.InvalidArgument);
	// }
	//
	// Properties pros = new Properties();
	// pros.setProperty("java.naming.factory.initial",
	// "org.jnp.interfaces.NamingContextFactory");
	//
	// try {
	// ctx = new InitialContext();
	// local = (LocalContainerOperation) ctx.lookup("ContainerBean/local");
	// return local.getMetaContainer(name);
	// } catch (NamingException e) {
	// throw new InternalException(ErrorCodes.InternalError);
	// }
	// }

	@Override
	public void setAuthorization(Principal principal) {
		this.principal = principal;
	}

	@Override
	public void createDataObject(InputDataObject object) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			obj_local = (LocalDataObjectOperation) ctx
					.lookup("DataObjectBean/local");
			// obj_local = new DataObjectBean();
			obj_local.createDataObject(object);
		} catch (NamingException e1) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public void deleteDataObject(String container, String objectUri) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			obj_local = (LocalDataObjectOperation) ctx
					.lookup("DataObjectBean/local");
			// obj_local = new DataObjectBean();
			// 校验ACL是否有删除权限
			obj_local.deleteDataObject(container, objectUri, principal);
		} catch (NamingException e1) {
			throw new InternalException(ErrorCodes.InternalError);
		}

	}

	@Override
	public DataObject getDataObject(String container, String objectUri) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			obj_local = (LocalDataObjectOperation) ctx
					.lookup("DataObjectBean/local");
			// obj_local = new DataObjectBean();
			// 校验ACL是否有删除权限
			return obj_local.getDataObject(container, objectUri, principal);
		} catch (NamingException e1) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public void setAccessControlPolicy(String container, String objectUri,
			AccessControlList acl) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			obj_local = (LocalDataObjectOperation) ctx
					.lookup("DataObjectBean/local");
			// obj_local = new DataObjectBean();
			obj_local.setAccessControlPolicy(container, objectUri, acl,
					this.principal);
		} catch (NamingException e1) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public void setUserMetadata(String container, String objectUri,
			Map<String, String> metaMap) {

		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			obj_local = (LocalDataObjectOperation) ctx
					.lookup("DataObjectBean/local");
			// obj_local = new DataObjectBean();
			obj_local.setUserMetadata(container, objectUri, metaMap,
					this.principal);
		} catch (NamingException e) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public Map<String, String> getUserMetadata(String container,
			String objectUri) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			obj_local = (LocalDataObjectOperation) ctx
					.lookup("DataObjectBean/local");
			// obj_local = new DataObjectBean();
			return obj_local.getUserMetadata(container, objectUri,
					this.principal);
		} catch (NamingException e) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public DataObjectProperties getProperties(String container,
			String objectUri, boolean withMetadata) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");
		try {
			ctx = new InitialContext();
			obj_local = (LocalDataObjectOperation) ctx
					.lookup("DataObjectBean/local");
			// obj_local = new DataObjectBean();
			return obj_local.getProperties(container, objectUri, withMetadata,
					this.principal);
		} catch (NamingException e) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public Map<String, String> getAccessControlList(String container,
			String objectUri) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			obj_local = (LocalDataObjectOperation) ctx
					.lookup("DataObjectBean/local");
			// obj_local = new DataObjectBean();
			return obj_local.getAccessControlList(container, objectUri,
					this.principal);
		} catch (NamingException e1) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	@Override
	public MetaDataObject copyDataObject(String source, String container,
			String objectUri, boolean replaceFlag) {
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial",
				"org.jnp.interfaces.NamingContextFactory");

		try {
			ctx = new InitialContext();
			obj_local = (LocalDataObjectOperation) ctx
					.lookup("DataObjectBean/local");
			// obj_local = new DataObjectBean();
			return obj_local.copyDataObject(source, container, objectUri,
					replaceFlag, this.principal);
		} catch (NamingException e1) {
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

}
